package com.castle.fortress.admin.cms.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.castle.fortress.admin.cms.dto.CmsChannelDto;
import com.castle.fortress.admin.cms.entity.CmsChannelAuditEntity;
import com.castle.fortress.admin.cms.entity.CmsChannelEntity;
import com.castle.fortress.admin.cms.mapper.CmsChannelMapper;
import com.castle.fortress.admin.cms.service.CmsArticleService;
import com.castle.fortress.admin.cms.service.CmsChannelAuditService;
import com.castle.fortress.admin.cms.service.CmsChannelService;
import com.castle.fortress.common.entity.RespBody;
import com.castle.fortress.common.respcode.BizErrorCode;
import com.castle.fortress.common.utils.ConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * cms栏目/导航菜单配置表 服务实现类
 *
 * @author castle
 * @since 2022-03-09
 */
@Service
public class CmsChannelServiceImpl extends ServiceImpl<CmsChannelMapper, CmsChannelEntity> implements CmsChannelService {
    @Autowired
    private CmsChannelAuditService cmsChannelAuditService;
    @Autowired
    private CmsArticleService cmsArticleService;


    /**
    * 获取查询条件
    * @param cmsChannelDto
    * @return
    */
    public QueryWrapper<CmsChannelEntity> getWrapper(CmsChannelDto cmsChannelDto){
        QueryWrapper<CmsChannelEntity> wrapper= new QueryWrapper();
        if(cmsChannelDto != null){
            CmsChannelEntity cmsChannelEntity = ConvertUtil.transformObj(cmsChannelDto,CmsChannelEntity.class);
            wrapper.like(StrUtil.isNotEmpty(cmsChannelEntity.getTitle()),"title",cmsChannelEntity.getTitle());
            wrapper.like(StrUtil.isNotEmpty(cmsChannelEntity.getKeywords()),"keywords",cmsChannelEntity.getKeywords());
            wrapper.like(StrUtil.isNotEmpty(cmsChannelEntity.getName()),"name",cmsChannelEntity.getName());
            wrapper.eq(StrUtil.isNotEmpty(cmsChannelEntity.getCode()),"code",cmsChannelEntity.getCode());
            wrapper.like(cmsChannelEntity.getParentId() != null,"parent_id",cmsChannelEntity.getParentId());
			wrapper.eq(cmsChannelEntity.getShowflag() != null,"showflag",cmsChannelEntity.getShowflag());
            wrapper.like(cmsChannelEntity.getCategory() != null,"category",cmsChannelEntity.getCategory());
            wrapper.like(cmsChannelEntity.getModel() != null,"model",cmsChannelEntity.getModel());
			wrapper.eq(cmsChannelEntity.getAuditflag() != null,"auditflag",cmsChannelEntity.getAuditflag());
        }
        wrapper.orderByAsc("sort");
        return wrapper;
    }


    @Override
    public IPage<CmsChannelDto> pageCmsChannel(Page<CmsChannelDto> page, CmsChannelDto cmsChannelDto) {
        QueryWrapper<CmsChannelEntity> wrapper = getWrapper(cmsChannelDto);
        Page<CmsChannelEntity> pageEntity = new Page(page.getCurrent(), page.getSize());
        Page<CmsChannelEntity> cmsChannelPage=baseMapper.selectPage(pageEntity,wrapper);
        Page<CmsChannelDto> pageDto = new Page(cmsChannelPage.getCurrent(), cmsChannelPage.getSize(),cmsChannelPage.getTotal());
        pageDto.setRecords(ConvertUtil.transformObjList(cmsChannelPage.getRecords(),CmsChannelDto.class));
        return pageDto;
    }


    @Override
    public List<CmsChannelDto> listCmsChannel(CmsChannelDto cmsChannelDto){
        QueryWrapper<CmsChannelEntity> wrapper = getWrapper(cmsChannelDto);
        List<CmsChannelEntity> list = baseMapper.selectList(wrapper);
        return ConvertUtil.transformObjList(list,CmsChannelDto.class);
    }

    @Override
    public RespBody checkColumnRepeat(CmsChannelDto dto) {
        //校验code
        QueryWrapper<CmsChannelEntity> queryWrapper=new QueryWrapper();
        queryWrapper.eq("code",dto.getCode());
        List<CmsChannelEntity> list = baseMapper.selectList(queryWrapper);
        if(list != null && !list.isEmpty()){
            //新增
            if(dto.getId() == null){
                return RespBody.fail(BizErrorCode.CMS_CODE_EXIST_ERROR);
                //修改
            }else{
                for(CmsChannelEntity entity:list){
                    if(!entity.getId().equals(dto.getId())){
                        return RespBody.fail(BizErrorCode.CMS_CODE_EXIST_ERROR);
                    }
                }
            }
        }
        return RespBody.data("校验通过");
    }

    @Override
    public List<CmsChannelDto> cmsTagListCmsChannel(Map<String, Object> map) {
        return ConvertUtil.transformObjList(baseMapper.cmsTagListCmsChannel(map), CmsChannelDto.class);
    }

    @Override
    public List<CmsChannelDto> cmsTagPositionByDto(CmsChannelDto dto) {
        List<CmsChannelEntity> list = new ArrayList<>();
        if(dto==null || (dto.getId() == null && StrUtil.isEmpty(dto.getCode()))){
            return new ArrayList<>();
        }
        QueryWrapper<CmsChannelEntity> queryWrapper=new QueryWrapper();
        queryWrapper.eq(dto.getId()!=null,"id",dto.getId());
        queryWrapper.eq(StrUtil.isNotEmpty(dto.getCode()),"code",dto.getCode());
        List<CmsChannelEntity> entities =baseMapper.selectList(queryWrapper);
        if(entities==null || entities.size()!=1){
            return new ArrayList<>();
        }
        CmsChannelEntity self = entities.get(0);
        List<CmsChannelEntity> parents = null;
        //查询父级
        if(StrUtil.isNotEmpty(self.getParents())){
            queryWrapper=new QueryWrapper();
            queryWrapper.in("id",self.getParents().split(","));
            parents = baseMapper.selectList(queryWrapper);
            if(parents!=null && !parents.isEmpty()){
                //按顺序展示列表
                String[] ps = self.getParents().split(",");
                for(String pid:ps){
                    for(CmsChannelEntity p:parents){
                        if(pid.equals(p.getId()+"")){
                            list.add(p);
                            break;
                        }
                    }
                }
            }
        }
        list.add(self);
        return ConvertUtil.transformObjList(list,CmsChannelDto.class);
    }

    @Async
    @Override
    public void auditChild(CmsChannelDto cmsChannelDto,CmsChannelEntity oldEntity) {
        if(cmsChannelDto.getAuditflag()){
            //删除原有的审核人员
            if(oldEntity!=null && oldEntity.getAuditflag()){
                cmsChannelAuditService.removeByChannelId(cmsChannelDto.getId());
            }
            //绑定该栏目的审核人员信息
            if(cmsChannelDto.getAuditUser()!=null && !cmsChannelDto.getAuditUser().isEmpty()){
                List<CmsChannelAuditEntity> list=new ArrayList<>();
                for(Map<String,Object> m:cmsChannelDto.getAuditUser()){
                    if("true".equals(m.get("isSelf").toString())){
                        CmsChannelAuditEntity e=new CmsChannelAuditEntity();
                        e.setChannelId(cmsChannelDto.getId());
                        e.setAuditId(Long.parseLong(m.get("id").toString()));
                        list.add(e);
                    }
                }
                if(!list.isEmpty()){
                    cmsChannelAuditService.saveBatch(list);
                }
            }
        }else{
            //删除原有的审核人员
            if(oldEntity!=null && oldEntity.getAuditflag()){
                cmsChannelAuditService.removeByChannelId(cmsChannelDto.getId());
            }
        }
        //同步所有子集栏目的审核状态
        cmsChannelAuditService.removeByParentId(cmsChannelDto.getId());
        baseMapper.synchSub(cmsChannelDto.getId(),cmsChannelDto.getAuditflag());
        //由审核改为不审核 则待审核文章改为已发布、审核失败改为草稿箱
        if(oldEntity!=null && oldEntity.getAuditflag() && !cmsChannelDto.getAuditflag()){
            cmsArticleService.cancelAudit(oldEntity.getId());
        }

    }

    @Override
    public List<CmsChannelDto> authListCmsChannel(List<Long> roldIds) {
        List<CmsChannelDto> list = null;
        List<CmsChannelEntity> entities = baseMapper.authList(roldIds);
        list= ConvertUtil.transformObjList(entities,CmsChannelDto.class);
        for(CmsChannelDto d:list){
            d.setHasAuth(true);
        }
        return list;
    }

    @Override
    public List<CmsChannelDto> authTreeCmsChannel(List<Long> roldIds) {
        List<CmsChannelDto> list = authListCmsChannel(roldIds);
        //展示时需要展示到顶级
        Set<Long> ids=new HashSet<>();
        for(CmsChannelDto s:list){
            ids.add(s.getId());
        }
        List<Long> parentId =new ArrayList<>();
        List<CmsChannelDto> parentList=new ArrayList<>();
        for(CmsChannelDto s:list){
            if(s.getParentId()!=null&&!ids.contains(s.getParentId())){
                parentId.add(s.getParentId());
            }
        }
        if(!parentId.isEmpty()){
            QueryWrapper<CmsChannelEntity> wrapper=new QueryWrapper<>();
            wrapper.in("id",parentId);
            parentList= ConvertUtil.transformObjList(list(wrapper),CmsChannelDto.class);
            for(CmsChannelDto d:parentList){
                d.setHasAuth(false);
            }
            list.addAll(parentList);
        }
        do{
            parentId =new ArrayList<>();
            for(CmsChannelDto s:parentList){
                if(s.getParentId()!=null&&!ids.contains(s.getParentId())){
                    parentId.add(s.getParentId());
                }
            }
            if(!parentId.isEmpty()){
                QueryWrapper<CmsChannelEntity> wrapper=new QueryWrapper<>();
                wrapper.in("id",parentId);
                parentList= ConvertUtil.transformObjList(list(wrapper),CmsChannelDto.class);
                for(CmsChannelDto d:parentList){
                    d.setHasAuth(false);
                }
                list.addAll(parentList);
            }
        }while(!parentId.isEmpty());

        return ConvertUtil.listToTree(list);
    }
}

